﻿using UnityEngine;
using System.Collections;


/// <summary>
/// 공격당할 수 있는 객체
/// </summary>
public interface IVulnerable 
{
	float maxHP			{ get; }
	float curHP			{ get; }
	bool invulnerable	{ get; }
	Faction faction		{ get; }

	/// <summary>
	/// 공격 당했을 때
	/// </summary>
	/// <param name="attacker">Attacker.</param>
	void OnAttacked(IAttacker attacker);
	//void OnDie();
}

/// <summary>
/// 공격당할 수 있는 오브젝트 베이스
/// </summary>
public class VulnerableObject : MonoBehaviour, IVulnerable
{
	// Properties							   	
	
	[SerializeField]
	Faction			m_faction;							// 세력
	[SerializeField]								
	float			m_maxLife		= 1f;				// 최대 체력
	[SerializeField]									
	bool			m_invulnerable	= false;			// 체력 무적


	// Members


	Transform		m_localT;
	bool			m_isDead	= false;

	protected Transform localT
	{
		get
		{
			return m_localT;
		}
	}

	public float curHP
	{
		get;
		protected set;
	}

	public Faction faction
	{
		get
		{
			return m_faction;
		}
	}

	public float maxHP
	{
		get
		{
			return m_maxLife;
		}

		protected set
		{
			m_maxLife	= value;
		}
	}

	public bool invulnerable
	{
		get
		{
			return m_invulnerable;
		}
	}


	void Awake()
	{
		m_localT	= transform;
		curHP		= maxHP;
		OnInitialize();
	}


	/// <summary>
	/// 유저 초기화 루틴
	/// </summary>
	public virtual void OnInitialize()
	{

	}

	void Update()
	{
		if(m_localT.localPosition.y < 0)							// * 바닥에 추락할 시 죽음
		{
			Debug.Log(gameObject.name + " is fallen!");
			DoDie();
		}
	}

	/// <summary>
	/// 충돌 처리
	/// </summary>
	/// <param name="collision">Collision.</param>
	void  OnCollisionEnter2D(Collision2D collision)
	{
		IAttacker attacker	= collision.gameObject.GetComponent(typeof(IAttacker)) as IAttacker;
		if(attacker != null && attacker.validAttacker)			// * 충돌한 상대가 유효한 공격자인지 체크
		{
			if(attacker.faction != faction)	// 피아구분 체크 후 피격/공격적중 이벤트 처리
			{
				OnAttacked(attacker);

				if(faction != Faction.Neutral)
				{
					attacker.OnHit(this);
				}
			}
		}
	}

	/// <summary>
	/// 공격당했을 때 행동
	/// </summary>
	/// <param name="attacker">Attacker.</param>
	public virtual void OnAttacked(IAttacker attacker)
	{
		if(!m_invulnerable)										// * 무적이 아닐 경우 데미지
		{
			curHP -= attacker.damage;

			SoundManager.PlaySfx(SoundInfos.GetSfx("hit"), transform);
		}

		if(curHP <= 0)											// * 체력이 다 되면 죽음 호출
		{
			DoDie();
		}
	}

	public void DoDie()
	{
		if(!m_isDead)											// * 죽지 않은 경우만 호출(중복 죽음 방지)
		{
			m_isDead	= true;
			OnDie();
		}
	}

	protected virtual void OnDie()
	{
		Debug.Log(gameObject.name + " is dead!");
	}
}
